// +FHDR----------------------------------------------------------
// Copyright (c) 2023, RJMicro Technology Co.,Ltd.
// RJMicro Confidential Proprietary
// ---------------------------------------------------------------
// FILE NAME       : .v
// DEPARTMENT      : IC Dept
// AUTHOR          :
// AUTHOR'S EMAIL  :
// ---------------------------------------------------------------
//
// Description     :
// 12'h000  CR0
// 12'h004  CR1
// 12'h008  OTP
// 12'h00C  SR
// 12'h010  IER
// 12'h014  CIR
// 12'h018  CHCFG[%S]
// 12'h038  DATA[%S]
// 12'h058  TDATA
// 12'h060  TEST
// -FHDR
// ---------------------------------------------------------------

module adc_regfile (
    output                 cr0_aden            ,
    output                 cr0_dmaen           ,
    output                 cr0_cont            ,
    output                 cr0_pgaen           ,
    output [02:0]          cr0_seqlength       ,
    output           cr0_sw_trig         ,
    output                 cr0_trig_sel        ,
    output [01:0]          cr0_pga_spd         ,
    output [11:0]          cr1_tactive         ,
    output                 otp_otpen           ,
    output [12:0]          otp_tempmax         ,
    input                  sr_eoc              ,
    input                  sr_trigerr          ,
    input                  sr_otp              ,
    input                  sr_adcrdy           ,
    input                  sr_eot              ,
    output                 ier_eocie           ,
    output                 ier_trigerrie       ,
    output                 ier_otpie           ,
    output           cir_eocclr          ,
    output           cir_trigerrclr      ,
    output           cir_otpclr          ,
    output           cir_eotclr          ,
    output [04:0]          chcfg[%s]_chsel     ,
    output [02:0]          chcfg[%s]_pgagain   ,
    output [01:0]          chcfg[%s]_pgasel    ,
    output [09:0]          chcfg[%s]_trigdelay ,
    output [09:0]          chcfg[%s]_tsamp     ,
    input  [12:0]          data[%s]_adc_data   ,
    input  [04:0]          data[%s]_disp_chsel ,
    input  [12:0]          tdata_adc_data      ,
    input  [04:0]          tdata_disp_chsel    ,
    input  [02:0]          test_ana_ctrl_fsm   ,
    input  [02:0]          test_seq_ctrl_fsm   ,
    output                 test_cnt_valid      ,
    output [02:0]          test_ana_adc_debug_in,
    output [02:0]          test_dig_adc_debug_in,
    input                  test_dig_adc_debug_out,
    input                  test_debug_data     ,
    output [02:0]          test_ana_pga_debug_in,
    output [02:0]          test_dig_pga_debug_in,
    input                  test_dig_pga_debug_out,
    input                  pclk                ,
    input                  prstn               ,

    input                  psel                ,
    input  [11:0]          paddr               ,
    input                  penable             ,
    input                  pwrite              ,
    input  [31:0]          pwdata              ,
//    output                pready              ,
//    output                pslverr             ,
    output [31:0]          prdata
);

// ------------------------------------------------------------
// APB write read enable
// ------------------------------------------------------------
reg     [31:0]  ff_rdata;
wire            read_en   = psel && (~penable) && (~pwrite);
wire            write_en  = psel && (~penable) && pwrite;
wire    [11:0]  addr      = paddr;
wire    [31:0]  wdata     = pwdata;

always @(posedge pclk or negedge prst) begin
    if (!prst)
        prdata <= 32'b0;
    else if (read_en) 
        prdata <= ff_rdata[31:0];
end

// ------------------------------------------------------------
// Internal Signals
// ------------------------------------------------------------
reg             ff_cr0_aden         ;
reg             ff_cr0_dmaen        ;
reg             ff_cr0_cont         ;
reg             ff_cr0_pgaen        ;
reg     [02:0]  ff_cr0_seqlength    ;
reg       ff_cr0_sw_trig      ;
reg             ff_cr0_trig_sel     ;
reg     [01:0]  ff_cr0_pga_spd      ;
reg     [11:0]  ff_cr1_tactive      ;
reg             ff_otp_otpen        ;
reg     [12:0]  ff_otp_tempmax      ;
reg             ff_ier_eocie        ;
reg             ff_ier_trigerrie    ;
reg             ff_ier_otpie        ;
reg       ff_cir_eocclr       ;
reg       ff_cir_trigerrclr   ;
reg       ff_cir_otpclr       ;
reg       ff_cir_eotclr       ;
reg     [04:0]  ff_chcfg[%s]_chsel  ;
reg     [02:0]  ff_chcfg[%s]_pgagain;
reg     [01:0]  ff_chcfg[%s]_pgasel ;
reg     [09:0]  ff_chcfg[%s]_trigdelay;
reg     [09:0]  ff_chcfg[%s]_tsamp  ;
reg             ff_test_cnt_valid   ;
reg     [02:0]  ff_test_ana_adc_debug_in;
reg     [02:0]  ff_test_dig_adc_debug_in;
reg     [02:0]  ff_test_ana_pga_debug_in;
reg     [02:0]  ff_test_dig_pga_debug_in;

wire            wir_sr_eoc          ;
wire            wir_sr_trigerr      ;
wire            wir_sr_otp          ;
wire            wir_sr_adcrdy       ;
wire            wir_sr_eot          ;
wire    [12:0]  wir_data[%s]_adc_data;
wire    [04:0]  wir_data[%s]_disp_chsel;
wire    [12:0]  wir_tdata_adc_data  ;
wire    [04:0]  wir_tdata_disp_chsel;
wire    [02:0]  wir_test_ana_ctrl_fsm;
wire    [02:0]  wir_test_seq_ctrl_fsm;
wire            wir_test_dig_adc_debug_out;
wire            wir_test_debug_data ;
wire            wir_test_dig_pga_debug_out;
assign          wir_sr_eoc          = sr_eoc              ;
assign          wir_sr_trigerr      = sr_trigerr          ;
assign          wir_sr_otp          = sr_otp              ;
assign          wir_sr_adcrdy       = sr_adcrdy           ;
assign          wir_sr_eot          = sr_eot              ;
assign          wir_data[%s]_adc_data= data[%s]_adc_data[12:0];
assign          wir_data[%s]_disp_chsel= data[%s]_disp_chsel[04:0];
assign          wir_tdata_adc_data  = tdata_adc_data[12:0];
assign          wir_tdata_disp_chsel= tdata_disp_chsel[04:0];
assign          wir_test_ana_ctrl_fsm= test_ana_ctrl_fsm[02:0];
assign          wir_test_seq_ctrl_fsm= test_seq_ctrl_fsm[02:0];
assign          wir_test_dig_adc_debug_out= test_dig_adc_debug_out;
assign          wir_test_debug_data = test_debug_data     ;
assign          wir_test_dig_pga_debug_out= test_dig_pga_debug_out;

// ------------------------------------------------------------
// write_process
// ------------------------------------------------------------
wire     wren_cr0            = write_en & (addr[11:2] == 10'h0);
wire     wren_cr1            = write_en & (addr[11:2] == 10'h1);
wire     wren_otp            = write_en & (addr[11:2] == 10'h2);
wire     wren_ier            = write_en & (addr[11:2] == 10'h4);
wire     wren_cir            = write_en & (addr[11:2] == 10'h5);
wire     wren_chcfg[%s]      = write_en & (addr[11:2] == 10'h6);
wire     wren_test           = write_en & (addr[11:2] == 10'h18);

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cr0_aden <= 1'h0;
    else if (wren_cr0) begin
        ff_cr0_aden <= wdata[0];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cr0_dmaen <= 1'h0;
    else if (wren_cr0) begin
        ff_cr0_dmaen <= wdata[1];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cr0_cont <= 1'h0;
    else if (wren_cr0) begin
        ff_cr0_cont <= wdata[2];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cr0_pgaen <= 1'h0;
    else if (wren_cr0) begin
        ff_cr0_pgaen <= wdata[3];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cr0_seqlength <= 3'h0;
    else if (wren_cr0) begin
        ff_cr0_seqlength <= wdata[6:4];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cr0_sw_trig <= 1'h0;
    else if (wren_cr0)
        ff_cr0_sw_trig <= wdata[8];
    else 
        ff_cr0_sw_trig <= 1'h0;
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cr0_trig_sel <= 1'h0;
    else if (wren_cr0) begin
        ff_cr0_trig_sel <= wdata[12];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cr0_pga_spd <= 2'h2;
    else if (wren_cr0) begin
        ff_cr0_pga_spd <= wdata[14:13];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cr1_tactive <= 12'hf0;
    else if (wren_cr1) begin
        ff_cr1_tactive <= wdata[19:8];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_otp_otpen <= 1'h0;
    else if (wren_otp) begin
        ff_otp_otpen <= wdata[0];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_otp_tempmax <= 13'h0;
    else if (wren_otp) begin
        ff_otp_tempmax <= wdata[28:16];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_ier_eocie <= 1'h0;
    else if (wren_ier) begin
        ff_ier_eocie <= wdata[0];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_ier_trigerrie <= 1'h0;
    else if (wren_ier) begin
        ff_ier_trigerrie <= wdata[1];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_ier_otpie <= 1'h0;
    else if (wren_ier) begin
        ff_ier_otpie <= wdata[2];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cir_eocclr <= 1'h0;
    else if (wren_cir)
        ff_cir_eocclr <= wdata[0];
    else 
        ff_cir_eocclr <= 1'h0;
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cir_trigerrclr <= 1'h0;
    else if (wren_cir)
        ff_cir_trigerrclr <= wdata[1];
    else 
        ff_cir_trigerrclr <= 1'h0;
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cir_otpclr <= 1'h0;
    else if (wren_cir)
        ff_cir_otpclr <= wdata[2];
    else 
        ff_cir_otpclr <= 1'h0;
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_cir_eotclr <= 1'h0;
    else if (wren_cir)
        ff_cir_eotclr <= wdata[4];
    else 
        ff_cir_eotclr <= 1'h0;
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_chcfg[%s]_chsel <= 5'h0;
    else if (wren_chcfg[%s]) begin
        ff_chcfg[%s]_chsel <= wdata[4:0];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_chcfg[%s]_pgagain <= 3'h0;
    else if (wren_chcfg[%s]) begin
        ff_chcfg[%s]_pgagain <= wdata[9:7];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_chcfg[%s]_pgasel <= 2'h0;
    else if (wren_chcfg[%s]) begin
        ff_chcfg[%s]_pgasel <= wdata[11:10];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_chcfg[%s]_trigdelay <= 10'h0;
    else if (wren_chcfg[%s]) begin
        ff_chcfg[%s]_trigdelay <= wdata[21:12];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_chcfg[%s]_tsamp <= 10'h14;
    else if (wren_chcfg[%s]) begin
        ff_chcfg[%s]_tsamp <= wdata[31:22];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_test_cnt_valid <= 1'h0;
    else if (wren_test) begin
        ff_test_cnt_valid <= wdata[8];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_test_ana_adc_debug_in <= 3'h0;
    else if (wren_test) begin
        ff_test_ana_adc_debug_in <= wdata[14:12];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_test_dig_adc_debug_in <= 3'h0;
    else if (wren_test) begin
        ff_test_dig_adc_debug_in <= wdata[18:16];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_test_ana_pga_debug_in <= 3'h0;
    else if (wren_test) begin
        ff_test_ana_pga_debug_in <= wdata[26:24];
    end
end

always @(posedge pclk or negedge prstn) begin
    if (!prstn)
        ff_test_dig_pga_debug_in <= 3'h0;
    else if (wren_test) begin
        ff_test_dig_pga_debug_in <= wdata[30:28];
    end
end


// ------------------------------------------------------------
// read_process
// ------------------------------------------------------------

wire  [31:0]  wir_r_cr0      = {17'h0, ff_cr0_pga_spd[14:13], ff_cr0_trig_sel, 5'h0, ff_cr0_seqlength[6:4], ff_cr0_pgaen, ff_cr0_cont, ff_cr0_dmaen, ff_cr0_aden};
wire  [31:0]  wir_r_cr1      = {12'h0, ff_cr1_tactive[19:8], 8'h0};
wire  [31:0]  wir_r_otp      = {3'h0, ff_otp_tempmax[28:16], 15'h0, ff_otp_otpen};
wire  [31:0]  wir_r_sr       = {27'h0, wir_sr_eot, wir_sr_adcrdy, wir_sr_otp, wir_sr_trigerr, wir_sr_eoc};
wire  [31:0]  wir_r_ier      = {29'h0, ff_ier_otpie, ff_ier_trigerrie, ff_ier_eocie};
wire  [31:0]  wir_r_chcfg[%s]= {ff_chcfg[%s]_tsamp[31:22], ff_chcfg[%s]_trigdelay[21:12], ff_chcfg[%s]_pgasel[11:10], ff_chcfg[%s]_pgagain[9:7], 2'h0, ff_chcfg[%s]_chsel[4:0]};
wire  [31:0]  wir_r_data[%s] = {11'h0, wir_data[%s]_disp_chsel[20:16], 3'h0, wir_data[%s]_adc_data[12:0]};
wire  [31:0]  wir_r_tdata    = {11'h0, wir_tdata_disp_chsel[20:16], 3'h0, wir_tdata_adc_data[12:0]};
wire  [31:0]  wir_r_test     = {wir_test_dig_pga_debug_out, ff_test_dig_pga_debug_in[30:28], 1'h0, ff_test_ana_pga_debug_in[26:24], 2'h0, wir_test_debug_data, 1'h0, wir_test_dig_adc_debug_out, ff_test_dig_adc_debug_in[18:16], 1'h0, ff_test_ana_adc_debug_in[14:12], 3'h0, ff_test_cnt_valid, 1'h0, wir_test_seq_ctrl_fsm[6:4], 1'h0, wir_test_ana_ctrl_fsm[2:0]};

always @ (*) begin
    ff_rdata = 32'h0;
    if (read_en) begin
        case (addr[11:2])
            10'b0000000000     :    ff_rdata = wir_r_cr0;
            10'b0000000001     :    ff_rdata = wir_r_cr1;
            10'b0000000010     :    ff_rdata = wir_r_otp;
            10'b0000000011     :    ff_rdata = wir_r_sr;
            10'b0000000100     :    ff_rdata = wir_r_ier;
            10'b0000000110     :    ff_rdata = wir_r_chcfg[%s];
            10'b0000001110     :    ff_rdata = wir_r_data[%s];
            10'b0000010110     :    ff_rdata = wir_r_tdata;
            10'b0000011000     :    ff_rdata = wir_r_test;
            default: ff_rdata = 32'h0;
        endcase
    end
end
// ------------------------------------------------------------
// Assign
// ------------------------------------------------------------
assign  cr0_aden            = ff_cr0_aden         ;
assign  cr0_dmaen           = ff_cr0_dmaen        ;
assign  cr0_cont            = ff_cr0_cont         ;
assign  cr0_pgaen           = ff_cr0_pgaen        ;
assign  cr0_seqlength       = ff_cr0_seqlength    ;
assign  cr0_sw_trig         = ff_cr0_sw_trig      ;
assign  cr0_trig_sel        = ff_cr0_trig_sel     ;
assign  cr0_pga_spd         = ff_cr0_pga_spd      ;
assign  cr1_tactive         = ff_cr1_tactive      ;
assign  otp_otpen           = ff_otp_otpen        ;
assign  otp_tempmax         = ff_otp_tempmax      ;
assign  ier_eocie           = ff_ier_eocie        ;
assign  ier_trigerrie       = ff_ier_trigerrie    ;
assign  ier_otpie           = ff_ier_otpie        ;
assign  cir_eocclr          = ff_cir_eocclr       ;
assign  cir_trigerrclr      = ff_cir_trigerrclr   ;
assign  cir_otpclr          = ff_cir_otpclr       ;
assign  cir_eotclr          = ff_cir_eotclr       ;
assign  chcfg[%s]_chsel     = ff_chcfg[%s]_chsel  ;
assign  chcfg[%s]_pgagain   = ff_chcfg[%s]_pgagain;
assign  chcfg[%s]_pgasel    = ff_chcfg[%s]_pgasel ;
assign  chcfg[%s]_trigdelay = ff_chcfg[%s]_trigdelay;
assign  chcfg[%s]_tsamp     = ff_chcfg[%s]_tsamp  ;
assign  test_cnt_valid      = ff_test_cnt_valid   ;
assign  test_ana_adc_debug_in= ff_test_ana_adc_debug_in;
assign  test_dig_adc_debug_in= ff_test_dig_adc_debug_in;
assign  test_ana_pga_debug_in= ff_test_ana_pga_debug_in;
assign  test_dig_pga_debug_in= ff_test_dig_pga_debug_in;
// ------------------------------------------------------------
// End of the module
// ------------------------------------------------------------
endmodule
